package edu.uob;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class QueryParser {
//    public static void main(String[] args) {
//        // Create a sample table
//        Table table = createSampleTable();
//
//            if (table != null) {
//                System.out.println("Table name: " + table.getTableName());
//                System.out.println("Column names: " + table.getColumnNames());
//                System.out.println("Rows:");
//                for (Row row : table.getRows()) {
//                    System.out.println(row.getRowData());
//                }
//            }
//
//        // Execute a sample query
//        String query = "SELECT id,name FROM SampleTable WHERE (mark==70) AND (id==1) ";
//
//        List<Map<String, Object>> result = executeQuery(table, query);
//
//        // Display the result
//        System.out.println("Query result:");
//        for (Map<String, Object> row : result) {
//            System.out.println(row);
//        }
//    }
//
//
//    private static Table createSampleTable() {
//        String filePath = "C:\\Users\\92529\\Desktop\\java\\JAVA-CW-2023\\cw-db\\databases\\456\\123.tab";
//        return readTableFromFile(filePath);
//    }

    public static List<Map<String, Object>> executeQuery(Table table, String query) {
        List<Map<String, Object>> result = new ArrayList<>();
        String[] parts = query.split("\\s+");
        // Assuming the query is well-formed
        if (parts.length >= 4 && parts[0].equalsIgnoreCase("SELECT") && parts[2].equalsIgnoreCase("FROM")) {
            String wildAttribList = parts[1];
            boolean hasWhereClause = parts.length > 5 && parts[4].equalsIgnoreCase("WHERE");
            if (hasWhereClause) {
                // Query with WHERE clause
                StringBuilder allCondition = new StringBuilder();
                for (int i = 5; i < parts.length; i++) {
                    allCondition.append(parts[i]);
                }
                result = handleCondition(table, allCondition.toString());
            } else {
                // Query without WHERE clause
                for (Row row : table.getRows()) {
                    result.add(row.getRowData());
                }
            }

            if (!wildAttribList.equals("*")) {
                result = handleWildAttribList(result, wildAttribList);
            }
        } else {
            // Invalid query
            System.out.println("Error: Invalid query format.");
        }
        return result;
    }

    public static List<Map<String, Object>> handleWildAttribList(List<Map<String, Object>> result, String wildAttribList) {
        List<Map<String, Object>> filteredResult = new ArrayList<>();
        // 将属性列表分割成单独的属性
        String[] attribs = wildAttribList.split(",");

        // 遍历原始结果列表
        for (Map<String, Object> map : result) {
            // 创建一个新的Map来存储过滤后的数据
            Map<String, Object> filteredData = new LinkedHashMap<>();
            // 遍历属性列表，将符合条件的键值对加入新的Map中
            for (String attrib : attribs) {
                if (map.containsKey(attrib)) {
                    filteredData.put(attrib, map.get(attrib));
                }
            }
            // 将新的Map加入过滤后的结果列表
            filteredResult.add(filteredData);
        }
        return filteredResult;
    }

    public static List<Map<String, Object>> handleCondition(Table table, String allCondition) {
        List<Map<String, Object>> result = new ArrayList<>();
        String cleanedCondition = allCondition.replaceAll("[()]", "");
        cleanedCondition = cleanedCondition.replaceAll("\\s+", "");
        // 使用正则表达式分割字符串为单个条件
        String[] conditions = cleanedCondition.split("(?=(AND|OR))|(?<=(AND|OR))");
        // 初始化存储 AND 和 OR 操作符的列表
        List<String> operators = new ArrayList<>();
        // 初始化存储条件的列表
        List<String> conditionList = new ArrayList<>();
        List<Condition> parsedConditionList = new ArrayList<>();
        // 提取条件和操作符
        for (String str : conditions) {
            if (str.equals("AND") || str.equals("OR")) {
                operators.add(str);
            } else {
                conditionList.add(str);
            }
        }
        // 输出结果
        //condition
        for (String condition : conditionList) {
            Condition parsedCondition = parseCondition(condition);
            parsedConditionList.add(parsedCondition);
        }


        if (parsedConditionList.toArray().length == 0) {
            System.out.println("Error: Invalid condition.");
            return result;
        }

        for (Row row : table.getRows()) {
            List<Boolean> rowConditionResult = new ArrayList<>();
            Map<String, Object> rowDataMap = row.getRowData();
            Object[] rowDataArray = rowDataMap.values().toArray(new Object[0]);

            for (Condition condition : parsedConditionList) {
                rowConditionResult.add(satisfiesCondition(table.getColumnNames(), rowDataArray, condition.toString()));
                System.out.println( "condition  "+condition);
            }
            System.out.println("rowConditionResult  "+rowConditionResult);

            String sss = restoreExpression(allCondition, rowConditionResult.toArray(new Boolean[0]));
            System.out.println("sasss "+ sss);
// 恢复表达式并计算结果

            if (evaluateExpression(sss)) {
                result.add(rowDataMap);
            }
        }
        return result;
    }

    public static String restoreExpression(String allCondition, Boolean[] booleanArray) {

        allCondition = allCondition.replaceAll("\\s", ""); // 去除表达式中的所有空格
        allCondition = allCondition.replaceAll(";", ""); // 去除表达式中的所有空格

        StringBuilder restoredExpression = new StringBuilder();
        Pattern pattern = Pattern.compile("\\(|\\)|\\b(AND|OR)\\b|[^\\s()]+");
        Matcher matcher = pattern.matcher(allCondition);

        int index = 0;
        int conditionCount = 0; // 声明并初始化条件计数

        while (matcher.find()) {
            if (matcher.group().matches("AND|OR|\\(|\\)")) {
                // 如果是AND、OR、括号等连接词，则直接附加到结果中
                restoredExpression.append(matcher.group());

            } else {
                // 否则，匹配到条件部分，替换为对应的布尔值
                if (index < booleanArray.length) {
                    restoredExpression.append(booleanArray[index] ? "TRUE" : "FALSE");
                    index++; // 确保索引增加在合法范围内
                    conditionCount++; // 每替换一个条件增加计数

                } else {
                    throw new IllegalArgumentException("Boolean array index out of bounds");
                }
            }
        }
        return restoredExpression.toString();
    }

    // T | F
    public static boolean evaluateExpression(String expression) {
        expression = expression.replaceAll("TRUE", "T").replaceAll("FALSE", "F").replaceAll("AND", "&").replaceAll("OR", "|");
        Stack<Character> operatorStack = new Stack<>();
        Stack<Boolean> operandStack = new Stack<>();

        for (char c : expression.toCharArray()) {
            if (c == 'T' || c == 'F') {
                operandStack.push(c == 'T');
            } else if (c == '(') {
                operatorStack.push(c);
            } else if (c == ')') {
                while (operatorStack.peek() != '(') {
                    evaluate(operandStack, operatorStack);
                }
                operatorStack.pop(); // Pop the '('
            } else if (c == '&' || c == '|') {
                while (!operatorStack.isEmpty() && precedence(operatorStack.peek()) >= precedence(c)) {
                    evaluate(operandStack, operatorStack);
                }
                operatorStack.push(c);
            }
        }

        while (!operatorStack.isEmpty()) {
            evaluate(operandStack, operatorStack);
        }

        return operandStack.pop();
    }

    private static void evaluate(Stack<Boolean> operandStack, Stack<Character> operatorStack) {
        char operator = operatorStack.pop();
        boolean operand2 = operandStack.pop();
        boolean operand1 = operandStack.pop();
        if (operator == '&') {
            operandStack.push(operand1 && operand2);
        } else if (operator == '|') {
            operandStack.push(operand1 || operand2);
        }
    }

    private static int precedence(char operator) {
        if (operator == '&') {
            return 2;
        } else if (operator == '|') {
            return 1;
        }
        return 0; // '('
    }


    private static Condition parseCondition(String conditionString) {
//        conditionString = conditionString.replaceAll(";", "");

        // Remove leading and trailing whitespaces
        conditionString = conditionString.trim();

        // Split by comparison operators
        String[] parts = conditionString.split("(?<=(==|>|<|>=|<=|!=|LIKE)|(?=(==|>|<|>=|<=|!=|LIKE)))\\s*", 3);

        if (parts.length == 3) {
            String attributeName = parts[0].trim();
            String comparator = parts[1].trim(); // Extract the comparator directly
            String value = parts[2].trim(); // Extract the value directly
            if (value.startsWith("'") && value.endsWith("'")) {
                value = value.substring(1, value.length() - 1); // Remove leading and trailing single quotes
            }

            // Create and return the condition object
            Condition condition = new Condition();
            condition.setAttributeName(attributeName);
            condition.setComparator(comparator);
            condition.setValue(value);
            return condition;
        }
        // Invalid condition
        return null;
    }
    static boolean satisfiesCondition(List<String> columnNames, Object[] rowData, String condition) {

        condition = condition.replaceAll(";", "");
        condition = condition.trim();

        // Split by comparison operators

        String[] parts = condition.split("(?<=(==|>|<|>=|<=|!=|LIKE)|(?=(==|>|<|>=|<=|!=|LIKE)))\\s*", 3);

        int conditionIndex = -1;
        for (int i = 0; i < columnNames.size(); i++) {
            if (columnNames.get(i).equals(parts[0].trim())) {
                conditionIndex = i;
                break;
            }
        }
        for (Object data : rowData) {
            System.out.println(data);
        }

        if (conditionIndex == -1) {
            System.err.println("Error: Column " + parts[0] + " specified in condition not found.");
            return false;
        }

        String tableValue = (String) rowData[conditionIndex];
        String conditionValue = parts[2];
        String conditionType;
        String[] type ={"string","int"};

        if (conditionValue.contains("'") || conditionValue.contains("TRUE") || conditionValue.contains("FALSE") || conditionValue.contains("NULL")){
            conditionType = type[0];
        } else {
            conditionType = type[1];
        }

        if(!parts[1].contains("LIKE")){//无like
            if(conditionType.contains("string")){
                String cleanConditionValue = conditionValue.replaceAll("'", "");


                return compareStrings(tableValue,cleanConditionValue,parts[1].trim());
                //按字符串处理
            } else {
                //按照数字处理

                return compareNumbers( tableValue,conditionValue,parts[1].trim());
            }
        }else {//like 都按字符串匹配
            String cleanConditionValue = conditionValue.replaceAll("'", "");

            return tableValue.contains(cleanConditionValue);
        }

    }

    public static boolean compareNumbers(String num1, String num2, String operator) {
        // 获取正负号
        int sign1 = num1.startsWith("+") ? 1 : num1.startsWith("-") ? -1 : 1;
        int sign2 = num2.startsWith("+") ? 1 : num2.startsWith("-") ? -1 : 1;

        // 移除正负号
        String cleanNum1 = removeSign(num1);
        String cleanNum2 = removeSign(num2);

        // 转换为数字类型
        double value1 = Double.parseDouble(cleanNum1) * sign1;
        double value2 = Double.parseDouble(cleanNum2) * sign2;

        // 执行比较
        return switch (operator) {
            case "==" -> value1 == value2;
            case ">" -> value1 > value2;
            case "<" -> value1 < value2;
            case ">=" -> value1 >= value2;
            case "<=" -> value1 <= value2;
            case "!=" -> value1 != value2;
            default -> throw new IllegalArgumentException("Invalid operator: " + operator);
        };
    }

    private static String removeSign(String num) {
        if (num.startsWith("+") || num.startsWith("-")) {
            return num.substring(1);
        } else {
            return num;
        }
    }

    public static boolean compareStrings(String str1, String str2, String operator) {
        // 执行比较
        return switch (operator) {
            case "==" -> str1.equals(str2);
            case "!=" -> !str1.equals(str2);
            case ">" -> str1.compareTo(str2) > 0;
            case "<" -> str1.compareTo(str2) < 0;
            case ">=" -> str1.compareTo(str2) >= 0;
            case "<=" -> str1.compareTo(str2) <= 0;
            default -> throw new IllegalArgumentException("Invalid operator: " + operator);
        };
    }
//    private static boolean satisfiesCondition(Map<String, Object> row, Condition condition) {
//        Object attributeValue = row.get(condition.getAttributeName());
//
//        if (attributeValue == null) {
//            System.out.println("Attribute value is null");
//            return false;
//        }
//
//        // 处理条件值为字符串字面值或者 NULL 的情况
//        if (condition.getValue() instanceof String || condition.getValue() == null) {
//            // 如果属性值不是字符串，则转换为字符串进行比较
//            if (!(attributeValue instanceof String)) {
//                attributeValue = attributeValue.toString();
//            }
//            // 处理 NULL 值的情况
//            if (condition.getValue() == null) {
//                System.out.println("Condition value is null");
//                return "NULL".equalsIgnoreCase((String) attributeValue);
//            }
//            // 去除条件值后面的分号
//            String conditionValue = condition.getValue().toString().trim();
//            conditionValue = conditionValue.replaceAll(";", ""); // 移除分号
//            System.out.println("Attribute value: " + attributeValue);
//            System.out.println("Condition value: " + conditionValue);
//            return performStringComparison((String) attributeValue, conditionValue, condition.getComparator());
//        }
//
//        // 处理条件值为布尔字面值的情况
//        if (condition.getValue() instanceof Boolean) {
//            // 如果属性值不是布尔型，则无法满足条件
//            if (!(attributeValue instanceof Boolean)) {
//                System.out.println("Attribute value is not a boolean");
//                return false;
//            }
//            // 去除条件值后面的分号
//            String conditionValue = condition.getValue().toString().trim();
//            conditionValue = conditionValue.replaceAll(";", ""); // 移除分号
//            System.out.println("Attribute value: " + attributeValue);
//            System.out.println("Condition value: " + conditionValue);
//            return performBooleanComparison((Boolean) attributeValue, Boolean.parseBoolean(conditionValue), condition.getComparator());
//        }
//
//        // 处理条件值为整数字面值的情况
//        if (condition.getValue() instanceof Integer) {
//            // 如果属性值不是整数类型，则无法满足条件
//            if (!(attributeValue instanceof Integer)) {
//                System.out.println("Attribute value is not an integer");
//                return false;
//            }
//            // 去除条件值后面的分号
//            String conditionValue = condition.getValue().toString().trim();
//            conditionValue = conditionValue.replaceAll(";", ""); // 移除分号
//            System.out.println("Attribute value: " + attributeValue);
//            System.out.println("Condition value: " + conditionValue);
//            return performNumericComparison((Integer) attributeValue, Integer.parseInt(conditionValue), condition.getComparator());
//        }
//
//        // 处理条件值为浮点字面值的情况
//        if (condition.getValue() instanceof Double || condition.getValue() instanceof Float) {
//            // 如果属性值不是浮点数类型，则无法满足条件
//            if (!(attributeValue instanceof Double) && !(attributeValue instanceof Float)) {
//                System.out.println("Attribute value is not a float");
//                return false;
//            }
//            // 去除条件值后面的分号
//            String conditionValue = condition.getValue().toString().trim();
//            conditionValue = conditionValue.replaceAll(";", ""); // 移除分号
//            System.out.println("Attribute value: " + attributeValue);
//            System.out.println("Condition value: " + conditionValue);
//            try {
//                double parsedAttributeValue = Double.parseDouble(attributeValue.toString());
//                // 如果解析成功，则进行比较
//                return performNumericComparison(parsedAttributeValue, Double.parseDouble(conditionValue), condition.getComparator());
//            } catch (NumberFormatException e) {
//                System.out.println("Error parsing attribute value to double: " + e.getMessage());
//                return false;
//            }
//        }
//        System.out.println("Unsupported condition value type");
//        return false; // 不支持的条件值类型
//    }

    // 执行字符串比较
    private static boolean performStringComparison(String attributeValue, String conditionValue, String comparator) {
        conditionValue = conditionValue.replaceAll("'", "");

        return switch (comparator) {
            case "==" -> attributeValue.equals(conditionValue);
            case "!=" -> !attributeValue.equals(conditionValue);
            case "LIKE" ->
                // 实现字符串匹配逻辑
                // 这里你可以根据你的需求实现 LIKE 操作符的逻辑，比如使用正则表达式进行匹配
                // 这里是一个简单的示例，你可以根据你的需求进行修改
                    attributeValue.contains(conditionValue);
            default -> {
                System.out.println("Unsupported string comparison operator: " + comparator);
                yield false;
            }
        };
    }

    // 执行布尔比较
    private static boolean performBooleanComparison(Boolean attributeValue, Boolean conditionValue, String comparator) {
        return switch (comparator) {
            case "==" -> attributeValue.equals(conditionValue);
            case "!=" -> !attributeValue.equals(conditionValue);
            default -> false; // 不支持的比较操作符
        };
    }

    // 执行数字比较
    private static <T extends Comparable<T>> boolean performNumericComparison(T attributeValue, T conditionValue, String comparator) {
        return switch (comparator) {
            case "==" -> attributeValue.compareTo(conditionValue) == 0;
            case ">" -> attributeValue.compareTo(conditionValue) > 0;
            case "<" -> attributeValue.compareTo(conditionValue) < 0;
            case "!=" -> attributeValue.compareTo(conditionValue) != 0;
            case ">=" -> attributeValue.compareTo(conditionValue) >= 0;
            case "<=" -> attributeValue.compareTo(conditionValue) <= 0;
            default -> false; // 不支持的比较操作符
        };
    }
}
